<?php
/**
 * User: YL
 * Date: 2019/6/10
 */

namespace app;

use Error;
use Exception;
use restful\ResultCode;
use restful\ResultException;
use restful\RuntimeCipher;
use restful\utils\log\Log;
use think\db\exception\DbException;
use think\exception\ErrorException;
use think\exception\Handle;
use think\exception\HttpException;
use think\Request;
use think\Response;
use Throwable;

class ExceptionHandle extends Handle
{
    protected $code = ResultCode::ERROR;
    protected $msg = '发生异常,请稍后重试~';
    protected $data;

    protected $httpCode = ResultCode::HTTP_ERROR_CODE;

    /**
     * 重写
     * @param Request $request
     * @param Throwable $e
     * @return Response
     */
    public function render($request, Throwable $e): Response
    {
        // 获取返回值
        $this->response($e);
        $response = [
            'code' => $this->code,
            'msg' => $this->msg,
            'data' => $this->data,
        ];

        // 返回数据处理
        $response = $this->resultHandle($response);

        return Response::create($response, 'json', $this->httpCode);
    }

    /**
     * 重写
     * @param Throwable $e
     */
    public function report(Throwable $e): void
    {}

    /**
     * 返回数据
     * @param Throwable $e
     */
    protected function response(Throwable $e)
    {
        if ($e instanceof ResultException) {
            // 返回异常
            $this->code = $e->getCode();
            $this->msg = $e->getMessage();
            $this->data = $e->getData();
            $this->httpCode = $e->getHttpCode();
        } elseif ($e instanceof HttpException) {
            // 请求异常
            $this->code = ResultCode::ERROR;
            $this->msg = 'Invaild request';
        } elseif ($e instanceof DbException) {
            // 数据库异常
            $this->code = ResultCode::SYS_EXCEPTION;
            $this->msg = '发生异常,请稍后重试~';
            Log::save('handle_db.exception', var_export($e->getData(), true) . PHP_EOL . $e->getTraceAsString());
        } elseif ($e instanceof Exception) {
            // 发生异常
            $this->code = ResultCode::SYS_EXCEPTION;
            $this->msg = '发生异常,请稍后重试~';
            Log::save('handle.exception', $e->getMessage() . PHP_EOL . $e->getTraceAsString());
        } elseif ($e instanceof ErrorException || $e instanceof Error) {
            // 发生错误
            $this->code = ResultCode::SYS_ERROR;
            $this->msg = '发生错误,请稍后重试~';
            Log::save('handle.error', $e->getMessage() . PHP_EOL . $e->getTraceAsString());
        }
    }

    /**
     * 返回处理
     * @param array $response
     * @return mixed
     */
    protected function resultHandle(array $response)
    {
        try {
            $response = RuntimeCipher::getInstance()->response($response);
        } catch (Throwable $e) {}

        return $response;
    }
}